//
//  KHBlueToothManager.m
//  KissHealth
//
//  Created by bingo on 2018/12/5.
//  Copyright © 2018 Mark. All rights reserved.
//

#import "KHBlueToothManager.h"
#import "BabyBluetooth.h"
#import "KHBlueToothHelper.h"

static NSString *kBloodMeterChannel = @"BloodMeterChannel";
static NSString *kBodyFatMeterChannel = @"WeightFatMeterChannel";
static NSString *kBloodPreMeterChannel = @"BloodPressureMeterChannel";

@interface KHBlueToothManager()

@property (strong, nonatomic) CBPeripheral *currentPeripheral;
@property (nonatomic, strong) CBCharacteristic *bloodPreWriteCharacteristic;

@property (nonatomic, assign) KHPeripheralType type;

@property (nonatomic, assign) BOOL isAutoReconnect;

@property (nonatomic, assign) NSInteger m_intImpedance; // 人体阻抗值

@end


@implementation KHBlueToothManager
{
    BabyBluetooth *baby;
    NSTimer *timerForWarn;
}

//单例模式
+ (instancetype)sharedManager {
    static KHBlueToothManager *share = nil;
    static dispatch_once_t oneToken;
    dispatch_once(&oneToken, ^{
        share = [[KHBlueToothManager alloc] init];
    });
    return share;
}


- (void)beginBlueToothMeterWithType:(KHPeripheralType)type block:(nonnull ReturnValueBlock)block{
    
    // 蓝牙单利已实例化且手机蓝牙未打开进行提示
    if (baby && (baby.centralManager.state != CBManagerStatePoweredOn)) {
        [KHBlueToothHelper showOpenBlueToothAlert];
    }
    
    self.type = type;
    self.block = block;
    self.isAutoReconnect = YES;
    if (type == KHPeripheralTypeBodyFat) {
        [[KHBlueToothManager sharedManager] beginBodyFatMeter];
    } else if (type == KHPeripheralTypeBloodPressure) {
        [self beginBloodPressureMeter];
    }
    else {
        [[KHBlueToothManager sharedManager] beginBloodMeter];
    }
}

- (void)beginBloodMeter {
    //初始化BabyBluetooth 蓝牙库
    baby = [BabyBluetooth shareBabyBluetooth];
    //设置蓝牙委托
    [self babyBloodChannelDelegate];
    //停止之前的连接
    [baby cancelAllPeripheralsConnection];
    //设置委托后直接可以使用，无需等待CBCentralManagerStatePoweredOn状态。
    baby.channel(kBloodMeterChannel).scanForPeripherals().begin();
    
    [self timerForScanWarn];
}

- (void)beginBodyFatMeter {
    
    self.m_intImpedance = 0;
    
    //初始化BabyBluetooth 蓝牙库
    baby = [BabyBluetooth shareBabyBluetooth];
    //设置蓝牙委托
    [self babyWeightFatMeterChannelDelegate];
    //停止之前的连接
    [baby cancelAllPeripheralsConnection];
    //设置委托后直接可以使用，无需等待CBCentralManagerStatePoweredOn状态。
    baby.channel(kBodyFatMeterChannel).scanForPeripherals().begin();
    
    [self timerForScanWarn];
}

- (void)beginBloodPressureMeter {
    //初始化BabyBluetooth 蓝牙库
    baby = [BabyBluetooth shareBabyBluetooth];
    //设置蓝牙委托
    [self babyBloodPreMeterChannelDelegate];
    //停止之前的连接
    [baby cancelAllPeripheralsConnection];
    //设置委托后直接可以使用，无需等待CBCentralManagerStatePoweredOn状态。
    baby.channel(kBloodPreMeterChannel).scanForPeripherals().begin();
    
    [self timerForScanWarn];
}

/// 连接设备
- (void)connectToPeripheralAtChannel:(NSString *)channel {
    baby.having(self.currentPeripheral).and.channel(channel).then.enjoy();
}

- (void)stopPeripheralsConnection {
    self.isAutoReconnect = NO;
    [baby cancelScan];
    [baby cancelAllPeripheralsConnection];
    [self stopScanWarn];
}

/// 自动重连设备或删除自动重连
- (void)autoReconnectPeripheral:(CBPeripheral *)peripheral {
    if (self.isAutoReconnect) {
        [baby AutoReconnect:peripheral];
    } else {
        [baby AutoReconnectCancel:peripheral];
    }
}


#pragma mark -蓝牙配置委托和操作

// 监听通知
- (void)notifyAtChannel:(NSString *)channel perpheral:(CBPeripheral *)peripheral characteristic:(CBCharacteristic *)characteristic {
    
    if (channel == kBloodMeterChannel) {
        [self notifyBloodChannel:peripheral characteristic:characteristic];
    } else if (channel == kBodyFatMeterChannel) {
        [self notifyBodyFatChannel:peripheral characteristic:characteristic];
    } else if (channel == kBloodPreMeterChannel) {
        [self notifyBloodPreChannel:peripheral characteristic:characteristic];
    }
    
}

#pragma mark - 血糖和胆固醇
-(void)babyBloodChannelDelegate {
    __weak typeof(self) weakSelf = self;
    [baby setBlockOnCentralManagerDidUpdateStateAtChannel:kBloodMeterChannel block:^(CBCentralManager *central) {
        if (central.state == CBCentralManagerStatePoweredOn) {
            [KHProgressHUD showInfoWithStatus:@"蓝牙已打开,开始扫描设备"];
        } else if (central.state == CBCentralManagerStatePoweredOff) {
//            [KHBlueToothHelper showOpenBlueToothAlert];
        }
    }];
    
    //设置查找设备的过滤器
    [baby setFilterOnDiscoverPeripheralsAtChannel:kBloodMeterChannel filter:^BOOL(NSString *peripheralName, NSDictionary *advertisementData, NSNumber *RSSI) {
        
        //最常用的场景是查找某一个前缀开头的设备 BeneCheck TC-B DONGLE
        if ([peripheralName hasPrefix:@"BeneCheck"] ) {
            return YES;
        }
        return NO;
        
    }];
    
    //设置扫描到设备的委托
    [baby setBlockOnDiscoverToPeripheralsAtChannel:kBloodMeterChannel block:^(CBCentralManager *central, CBPeripheral *peripheral, NSDictionary *advertisementData, NSNumber *RSSI) {
        NSLog(@"搜索到了设备:%@",peripheral.name);
        [KHProgressHUD showInfoWithStatus:@"扫描到设备,开始进行连接..."];
        weakSelf.currentPeripheral = peripheral;
        [weakSelf connectToPeripheralAtChannel:kBloodMeterChannel];
    }];
    
    //设置设备连接失败的委托
    [baby setBlockOnFailToConnectAtChannel:kBloodMeterChannel block:^(CBCentralManager *central, CBPeripheral *peripheral, NSError *error) {
        [KHProgressHUD showInfoWithStatus:@"设备连接失败,请重试!"];
    }];
    
    //设置设备断开连接的委托
    [baby setBlockOnDisconnectAtChannel:kBloodMeterChannel block:^(CBCentralManager *central, CBPeripheral *peripheral, NSError *error) {
        [KHProgressHUD showInfoWithStatus:@"设备连接已断开"];
        [weakSelf autoReconnectPeripheral:peripheral];
    }];
    
    //设置设备连接成功的委托
    [baby setBlockOnConnectedAtChannel:kBloodMeterChannel block:^(CBCentralManager *central, CBPeripheral *peripheral) {
        
        [weakSelf stopScanWarn];
        NSLog(@"设备：%@--连接成功",peripheral.name);
        [KHProgressHUD showInfoWithStatus:@"设备连接成功"];
    }];
    
    //设置发现设备的Services的委托
    [baby setBlockOnDiscoverServicesAtChannel:kBloodMeterChannel block:^(CBPeripheral *peripheral, NSError *error) {}];
    
    //设置发现设service的Characteristics的委托
    [baby setBlockOnDiscoverCharacteristicsAtChannel:kBloodMeterChannel block:^(CBPeripheral *peripheral, CBService *service, NSError *error) {
        if (![service.UUID.UUIDString isEqualToString:kBloodServiceUUID]) return;
        for (CBCharacteristic *c in service.characteristics) {
            if ([c.UUID.UUIDString isEqualToString:kBloodReadCharacteristicUUID]) {
                [weakSelf notifyAtChannel:kBloodMeterChannel perpheral:peripheral characteristic:c];
            } else if ([c.UUID.UUIDString isEqualToString:kBloodNotificationUUID]) {
                // 监听通知
                [weakSelf notifyAtChannel:kBloodMeterChannel perpheral:peripheral characteristic:c];
            }
            
        }
    }];
    
    //设置读取characteristics的委托
    [baby setBlockOnReadValueForCharacteristicAtChannel:kBloodMeterChannel block:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) {
        
        NSLog(@"characteristic UUID:%@ value is:%@",characteristics.UUID.UUIDString, characteristics.value);
        if (![characteristics.UUID.UUIDString isEqualToString:kBloodReadCharacteristicUUID]) return;
        
        NSData * data = characteristics.value;
        if (!data || data.length != 20) return;
        
        if ([weakSelf checkSum:data]) {
            [weakSelf handleBloodChannelResultData:data];
        }
    }];
    
    //设置发现characteristics的descriptors的委托
    [baby setBlockOnDiscoverDescriptorsForCharacteristicAtChannel:kBloodMeterChannel block:^(CBPeripheral *peripheral, CBCharacteristic *characteristic, NSError *error) {
        
    }];
    
    //设置读取Descriptor的委托
    [baby setBlockOnReadValueForDescriptorsAtChannel:kBloodMeterChannel block:^(CBPeripheral *peripheral, CBDescriptor *descriptor, NSError *error) {
    }];
    
    //characteristic订阅状态改变的block
    [baby setBlockOnDidUpdateNotificationStateForCharacteristicAtChannel:kBloodMeterChannel block:^(CBCharacteristic *characteristic, NSError *error) {
        NSLog(@"characteristic new value %@", characteristic.value);
    }];
    
}


/// 订阅血糖胆固醇读特征值
- (void)notifyBloodChannel:(CBPeripheral *)peripheral characteristic:(CBCharacteristic *)characteristic {
    __weak typeof(self) weakSelf = self;
    [baby notify:peripheral characteristic:characteristic block:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) {
        // 2450434c 41000000 09000000 120b1008 08000066
        // 处理接收到的数据
        NSData * data = characteristic.value;
        if (!data || data.length != 20) return;
        if ([weakSelf checkSum:data]) {
            [weakSelf handleBloodChannelResultData:data];
        }
    }];
}

/// 检验接收到的数据
- (BOOL)checkSum:(NSData *)data {
    
    Byte *value = (Byte *)[data bytes];

    // 数据累加和校验格式说明：如：测量结果为24 50 43 4C 51 00 00 00 09 00 00 00 11 03 15 11 17 3E 00 C8
    //从第二位开始累加到倒数第二位，取累加值的低位字节为checkSum
    Byte tmpData = 0;
    for(int i = 1; i < 19; i++) {
        tmpData += value[i];
    }
    return value[19] == tmpData;
}

/// 处理接收到的数据
- (void)handleBloodChannelResultData:(NSData *)data {
    
    Byte *values = (Byte *)[data bytes];
    
    // 根据协议计算相应的值
    CGFloat resultValue = 0.0f;
    switch (values[4]) {
        case 0x41://血糖GLU,单位：1mg/dl,单位换算GLU:1mmol/L = 18mg/dl
        {
            int temp = ((values[18]&0xff)<<8) + (values[17]&0xff);
            resultValue = temp/18.0;
        }
            break;
            
        case 0x51://尿酸UA,单位：0.1mg/dl,单位换算UA:1mmol/L = 16.81mg/dl,此处使用umol/L
        {
            int temp1 = ((values[18]&0xff)<<8) + (values[17]&0xff);
            resultValue = temp1*0.1/16.81*1000;
            
        }
            break;
            
        case 0x61://胆固醇CHOL,单位：1mg/dl,单位换算CHOL:1mmol/L = 38.66mg/dl,此处使用mmol/L
        {
            int temp2 = ((values[18]&0xff)<<8) + (values[17]&0xff);
            resultValue = temp2/38.66;
        }
            break;
            
        default:
            break;
    }
    
    // 处理回调的数据
    NSString *peripheralName = self.currentPeripheral.name;
    NSString *currentDate = [KHBlueToothHelper getCurrentDateTime];
    NSString *peripheralType = [KHBlueToothHelper meterStringForPeripheralType:self.type];
    NSString *dataHandleWay = @"1";
    
    NSString *deviceInfo = [NSString stringWithFormat:@"%@;%@;%@;", peripheralName, peripheralType, dataHandleWay];
    NSString *dataInfo = [NSString stringWithFormat:@"%@;%.2f;", currentDate, resultValue];
    
    NSString *transferString = [NSString stringWithFormat:@"%@&%@", deviceInfo, dataInfo];
    
    NSDictionary *dict = @{peripheralType : transferString};
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
    NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    
    if (self.block) {
        self.block(jsonString);
    }

}


#pragma mark - 体脂蓝牙
- (void)babyWeightFatMeterChannelDelegate {
    __weak typeof(self) weakSelf = self;
    [baby setBlockOnCentralManagerDidUpdateStateAtChannel:kBodyFatMeterChannel block:^(CBCentralManager *central) {
        if (central.state == CBCentralManagerStatePoweredOn) {
            [weakSelf _dispatchMessageInMainThread:^{
                [KHProgressHUD showInfoWithStatus:@"蓝牙已打开,开始扫描设备"];
            }];
        } else if (central.state == CBCentralManagerStatePoweredOff) {
            /**
            [weakSelf _dispatchMessageInMainThread:^{
                [KHBlueToothHelper showOpenBlueToothAlert];
            }];*/
        }
    }];
    
    //设置查找设备的过滤器
    [baby setFilterOnDiscoverPeripheralsAtChannel:kBodyFatMeterChannel filter:^BOOL(NSString *peripheralName, NSDictionary *advertisementData, NSNumber *RSSI) {
        //最常用的场景是查找某一个前缀开头的设备 eBody-Fat-Scale
        if ([peripheralName hasPrefix:@"eBody"] ) {
            return YES;
        }
        return NO;
    }];
    
    //设置设备连接失败的委托
    [baby setBlockOnFailToConnectAtChannel:kBodyFatMeterChannel block:^(CBCentralManager *central, CBPeripheral *peripheral, NSError *error) {
        [KHProgressHUD showInfoWithStatus:@"设备连接失败,请重试!"];
    }];
    
    //设置设备断开连接的委托
    [baby setBlockOnDisconnectAtChannel:kBodyFatMeterChannel block:^(CBCentralManager *central, CBPeripheral *peripheral, NSError *error) {
        [KHProgressHUD showInfoWithStatus:@"设备连接已断开"];
    }];
    
    //设置扫描到设备的委托
    [baby setBlockOnDiscoverToPeripheralsAtChannel:kBodyFatMeterChannel block:^(CBCentralManager *central, CBPeripheral *peripheral, NSDictionary *advertisementData, NSNumber *RSSI) {
        [KHProgressHUD showInfoWithStatus:@"扫描到设备,开始进行连接..."];
        weakSelf.currentPeripheral = peripheral;
        [weakSelf connectToPeripheralAtChannel:kBodyFatMeterChannel];
    }];
    
    //设置设备连接成功的委托
    [baby setBlockOnConnectedAtChannel:kBodyFatMeterChannel block:^(CBCentralManager *central, CBPeripheral *peripheral) {
        [weakSelf stopScanWarn];
        [KHProgressHUD showInfoWithStatus:@"设备连接成功"];
    }];

    //设置发现设备的Services的委托
    [baby setBlockOnDiscoverServicesAtChannel:kBodyFatMeterChannel block:^(CBPeripheral *peripheral, NSError *error) {
        
    }];
    
    //设置发现service的Characteristic的委托
    [baby setBlockOnDiscoverCharacteristicsAtChannel:kBodyFatMeterChannel block:^(CBPeripheral *peripheral, CBService *service, NSError *error) {
        NSLog(@"===service name:%@",service.UUID.UUIDString);
        for (CBCharacteristic *c in service.characteristics) {
            if ([service.UUID.UUIDString isEqualToString:kBodyFatServiceUUID]) {
                if ([c.UUID.UUIDString isEqualToString:kBodyFatWriteCharacteristicUUID]) {
                    NSLog(@"charateristic name is :%@",c.UUID);
                    
                    // 向设备写入个人参数设置,为了接收到完整的体脂数据
                    //byte[] data = new byte[]{(byte) 0xFD, 0x53, 0x00, 0x00, 0x40, (byte) 0x9F, (byte) 0xA7};
                    Byte dataValue[7] = {0xFD, 0x53, 0x00, 0x00, 0x40, 0x9F, 0xA7};
                    NSData *data = [NSData dataWithBytes:&dataValue length:sizeof(dataValue)];
                    
                    [peripheral writeValue:data forCharacteristic:c type:CBCharacteristicWriteWithResponse];
                } else if ([c.UUID isEqual:[CBUUID UUIDWithString:kBodyFatReadCharacteristicUUID]]) {
                    [weakSelf notifyAtChannel:kBodyFatMeterChannel perpheral:peripheral characteristic:c];
                } else if ([c.UUID isEqual:[CBUUID UUIDWithString:kBodyFatNotificationUUID]]) {
                    [weakSelf notifyAtChannel:kBodyFatMeterChannel perpheral:peripheral characteristic:c];
                }
            }
            
        }
    }];
    
    
    [baby setBlockOnDidWriteValueForCharacteristicAtChannel:kBodyFatMeterChannel block:^(CBCharacteristic *characteristic, NSError *error) {
        if ([characteristic.UUID.UUIDString isEqualToString:kBodyFatWriteCharacteristicUUID]) {
            NSString *value = [[NSString alloc] initWithData:characteristic.value encoding:NSASCIIStringEncoding];
            NSLog(@"characteristic UUID:%@ value is:%@",characteristic.UUID.UUIDString,value);
        } else if ([characteristic.UUID.UUIDString isEqualToString:kBodyFatWriteCharacteristicUUID]) {
            NSLog(@"characteristic UUID:%@ value is:%@",characteristic.UUID.UUIDString,characteristic.value);
        }
    }];
    
    //设置读取characteristics的委托
    [baby setBlockOnReadValueForCharacteristicAtChannel:kBodyFatMeterChannel block:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) {
        
        if ([characteristics.UUID.UUIDString isEqualToString:kBodyFatReadCharacteristicUUID]) {
            NSLog(@"characteristic name:%@ value is:%@",characteristics.UUID,characteristics.value);
        }
        
    }];
    
}


/// 订阅体脂特征
- (void)notifyBodyFatChannel:(CBPeripheral *)peripheral characteristic:(CBCharacteristic *)characteristic {
    __weak typeof(self) weakSelf = self;
    [baby notify:peripheral characteristic:characteristic block:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) {
        NSLog(@"notify characteristic name:%@ value is:%@",characteristics.UUID,characteristics.value);
        if ([characteristics.UUID isEqual: [CBUUID UUIDWithString:kBodyFatReadCharacteristicUUID]]) {
            [weakSelf _handleBodyFatData:characteristics.value];
        }
        
//        ff426600 00000000 409fa7dc 023a01ac 1904055e
    }];
}

/// 处理体脂数据
- (void)_handleBodyFatData:(NSData *)data {
    
    Byte *values = (Byte *)[data bytes];

    if (data != nil && data.length == 5) {
        self.m_intImpedance = ((values[3] & 0xff) << 8) | (values[4] & 0xff);
    } else if (data != nil && data.length == 20) {
        
        int weightInt = (values[2] & 0xFF) | (((values[1] & 0x3F) << 8) & 0xFF00);
        float weightFloat = weightInt / 10.f; //体重
        float fatFloat = 0; // 脂肪
        float boneFloat = 0; // 骨重
        float muscleFloat = 0; // 肌肉
        int visceraFat = 0; // 内脏脂肪
        float waterFloat = 0; // 水分
        int kcalInt = 0; // 热量
        int BMI = 0; // BMI
        int height = (int) ((values[19] & 0xFF) | (((Byte) 0 << 8) & 0xFF00) | (((short) 0 << 16) & 0xFFFF0000)); // 身高
        
        if (values[11] != 0xFF && (values[12] & 0xF0) != 0xF0) {
            
            int fatInt = (values[12] & 0xFF) | (((values[11] & 0xF0) << 8) & 0xFF00);
            fatFloat = fatInt / 10.f;
            
            int boneInt = ((values[16] & 0xFF) | (((Byte) 0 << 8) & 0xFF00) | (((short) 0 << 16) & 0xFFFF0000));
            boneFloat = boneInt / 10.f;
            
            int muscleInt = (values[15] & 0xFF) | ((values[14] << 8) & 0xFF00);
            muscleFloat = muscleInt / 10.f;
            
            visceraFat = ((values[17] & 0xFF) | (((Byte) 0 << 8) & 0xFF00) | (((short) 0 << 16) & 0xFFFF0000));;
            
            int waterInt = (values[13] & 0xFF) | (((values[12] & 0xF0) << 8) & 0xFF00);
            waterFloat = waterInt / 10.f;
            
            kcalInt = (values[19] & 0xFF) | ((values[18] << 8) & 0xFF00);
            
            BMI = waterInt * 1000 / (height * height);
        }
        
        NSString *dataString = [NSString stringWithFormat:@"%.1f;%d;%f;%f;%.f;%d;%.f;%d;%d;0;0;%ld", weightFloat,BMI,muscleFloat,boneFloat,fatFloat,visceraFat,waterFloat,height,kcalInt,(long)self.m_intImpedance];
        
        
        // 处理回调的数据
        NSString *peripheralName = self.currentPeripheral.name;
        NSString *currentDate = [KHBlueToothHelper getCurrentDateTime];
        NSString *peripheralType = [KHBlueToothHelper meterStringForPeripheralType:self.type];
        NSString *dataHandleWay = @"1";
        
        NSString *deviceInfo = [NSString stringWithFormat:@"%@;%@;%@;", peripheralName, peripheralType, dataHandleWay];
        NSString *dataInfo = [NSString stringWithFormat:@"%@;%@;", currentDate, dataString];
        
        NSString *transferString = [NSString stringWithFormat:@"%@&%@", deviceInfo, dataInfo];
        
        NSDictionary *dict = @{peripheralType : transferString};
        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
        NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
        
        if (self.block) {
            self.block(jsonString);
        }
    }
}


#pragma mark - 血压测量
- (void)babyBloodPreMeterChannelDelegate {
    __weak typeof(self) weakSelf = self;
    [baby setBlockOnCentralManagerDidUpdateStateAtChannel:kBloodPreMeterChannel block:^(CBCentralManager *central) {
        if (central.state == CBCentralManagerStatePoweredOn) {
            [weakSelf _dispatchMessageInMainThread:^{
                [KHProgressHUD showInfoWithStatus:@"蓝牙已打开,开始扫描设备"];
            }];
        } else if (central.state == CBCentralManagerStatePoweredOff) {
            
        } else {
            [KHBlueToothHelper showOpenBlueToothAlert];
        }
    }];
    
    //设置查找设备的过滤器
    [baby setFilterOnDiscoverPeripheralsAtChannel:kBloodPreMeterChannel filter:^BOOL(NSString *peripheralName, NSDictionary *advertisementData, NSNumber *RSSI) {
        //最常用的场景是查找某一个前缀开头的设备 AES-XY
        if ([peripheralName hasPrefix:@"AES"] ) {
            return YES;
        }
        return NO;
    }];
    
    //设置设备连接失败的委托
    [baby setBlockOnFailToConnectAtChannel:kBloodPreMeterChannel block:^(CBCentralManager *central, CBPeripheral *peripheral, NSError *error) {
        [KHProgressHUD showInfoWithStatus:@"设备连接失败,请重试!"];
    }];
    
    //设置设备断开连接的委托
    [baby setBlockOnDisconnectAtChannel:kBloodPreMeterChannel block:^(CBCentralManager *central, CBPeripheral *peripheral, NSError *error) {
        [KHProgressHUD showInfoWithStatus:@"设备连接已断开"];
    }];
    
    //设置扫描到设备的委托
    [baby setBlockOnDiscoverToPeripheralsAtChannel:kBloodPreMeterChannel block:^(CBCentralManager *central, CBPeripheral *peripheral, NSDictionary *advertisementData, NSNumber *RSSI) {
        [KHProgressHUD showInfoWithStatus:@"扫描到设备,开始进行连接..."];
        weakSelf.currentPeripheral = peripheral;
        [weakSelf connectToPeripheralAtChannel:kBloodPreMeterChannel];
    }];
    
    //设置设备连接成功的委托
    [baby setBlockOnConnectedAtChannel:kBloodPreMeterChannel block:^(CBCentralManager *central, CBPeripheral *peripheral) {
        [weakSelf stopScanWarn];
        [KHProgressHUD showInfoWithStatus:@"设备连接成功"];
    }];
    
    //设置发现设备的Services的委托
    [baby setBlockOnDiscoverServicesAtChannel:kBloodPreMeterChannel block:^(CBPeripheral *peripheral, NSError *error) {
        
    }];
    
    //设置发现service的Characteristic的委托
    [baby setBlockOnDiscoverCharacteristicsAtChannel:kBloodPreMeterChannel block:^(CBPeripheral *peripheral, CBService *service, NSError *error) {
        NSLog(@"===service name:%@",service.UUID.UUIDString);
        for (CBCharacteristic *c in service.characteristics) {
            
            if ([c.UUID isEqual:[CBUUID UUIDWithString:kBloodPreWriteCharacteristicUUID]]) {
                weakSelf.bloodPreWriteCharacteristic = c;
            }
            
            BOOL isNotify = [c.UUID isEqual:[CBUUID UUIDWithString:kBloodPreReadCharacteristicUUID]];
            
            if (isNotify) {
                [weakSelf notifyAtChannel:kBloodPreMeterChannel perpheral:peripheral characteristic:c];
            }
        }
    }];
    
}


/// 订阅血压特征
- (void)notifyBloodPreChannel:(CBPeripheral *)peripheral characteristic:(CBCharacteristic *)characteristic {
    __weak typeof(self) weakSelf = self;
    [baby notify:peripheral characteristic:characteristic block:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) {
        
        if ([characteristics.UUID isEqual: [CBUUID UUIDWithString:kBloodPreReadCharacteristicUUID]]) {
            [weakSelf _handleBloodPreData:characteristics.value];
        }
        
    }];
}

/// 处理血压数据
- (void)_handleBloodPreData:(NSData *)data {
    Byte *values = (Byte *)[data bytes];
    if (13 != data.length || ![self isBloodPreDataExactWithData:data]) {
        return;
    }
    
    int systolic = [self _getResultWithLowByte:values[3] highByte:values[4]]; // 收缩压
    int diastolic = [self _getResultWithLowByte:values[5] highByte:values[6]]; // 舒张压
    int heartRate = [self _getResultWithLowByte:values[7] highByte:values[8]]; // 心率
    
    // 心率;脉率;舒张压;收缩压;
    NSString *dataString = [NSString stringWithFormat:@"%d;0;%d;%d", heartRate, diastolic, systolic];
    
    // 处理回调的数据
    NSString *peripheralName = self.currentPeripheral.name;
    NSString *currentDate = [KHBlueToothHelper getCurrentDateTime];
    NSString *peripheralType = [KHBlueToothHelper meterStringForPeripheralType:self.type];
    NSString *dataHandleWay = @"1";
    
    NSString *deviceInfo = [NSString stringWithFormat:@"%@;%@;%@;", peripheralName, peripheralType, dataHandleWay];
    NSString *dataInfo = [NSString stringWithFormat:@"%@;%@;", currentDate, dataString];
    
    NSString *transferString = [NSString stringWithFormat:@"%@&%@", deviceInfo, dataInfo];
    
    NSDictionary *dict = @{peripheralType : transferString};
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
    NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    
    if (self.block) {
        self.block(jsonString);
    }
    
    [self _stopBloodPreMeter];
    
}

- (void)_stopBloodPreMeter {
    Byte value[8]={0};
    value[0]=0xFD;
    value[1]=0xFD;
    value[2]=0x05;
    value[3]=0x05;
    value[4]=0x05;
    value[5]=0x05;
    value[6]=0x0D;
    value[7]=0x0A;
    NSData * data = [NSData dataWithBytes:&value length:sizeof(value)];
    [self.currentPeripheral writeValue:data forCharacteristic:self.bloodPreWriteCharacteristic type:CBCharacteristicWriteWithoutResponse];
    
    
    [KHProgressHUD showInfoWithStatus:@"测量完毕"];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self stopPeripheralsConnection];
    });
}

- (BOOL)isBloodPreDataExactWithData:(NSData *)data {
    Byte *values = (Byte *)[data bytes];
    Byte real = values[data.length - 3];
    int tempSum = values[0] + values[1] + values[2] + [self _getResultWithLowByte:values[3] highByte:values[4]] + [self _getResultWithLowByte:values[5] highByte:values[6]] + [self _getResultWithLowByte:values[7] highByte:values[8]] + values[9] + values[11] + values[12];
    Byte checkcum = (Byte)(tempSum % 256);
    return checkcum == real;
}



- (int)_getResultWithLowByte:(Byte)lowByte highByte:(Byte)highByte {
    // 高位大于0x0A,加10并乘16处理
    int result = highByte >= 0x41 ? (highByte - 0x41 + 10) * 16 : (highByte - 0x30) * 16;
    
    // 低位大于0x0A,加10处理 并加上高位
    result =  (lowByte >= 0x41 ? lowByte - 0x41 + 10 : lowByte - 0x30) + result;
    return result;
}



#pragma mark - 主线程执行更新
// 主线程执行更新UI
- (void)_dispatchMessageInMainThread:(DISPATCH_NOESCAPE dispatch_block_t)block {
    if ([[NSThread currentThread] isMainThread]) {
        block();
    } else {
        dispatch_sync(dispatch_get_main_queue(), block);
    }
}

#pragma mark - 搜索超时提示定时
- (void)timerForScanWarn {
    //听见定时器执行
    timerForWarn = [NSTimer timerWithTimeInterval:30 target:self selector:@selector(scanFailWarn) userInfo:nil repeats:NO];
    [timerForWarn setFireDate: [[NSDate date] dateByAddingTimeInterval:30]];
    [[NSRunLoop currentRunLoop] addTimer:timerForWarn forMode:NSRunLoopCommonModes];
}

- (void)scanFailWarn {
    
    [KHProgressHUD showInfoWithStatus:@"未搜索到相关设备或本机蓝牙未打开"];
    
    [self stopScanWarn];
}

- (void)stopScanWarn {
    
    [timerForWarn invalidate];
    timerForWarn = nil;
    
}

@end
